package com.micro.platform.oauth.config.oauth.grant;

import com.micro.platform.oauth.domain.LocalClientDetails;
import com.micro.platform.oauth.framework.OauthManager;
import com.micro.platform.oauth.framework.domain.*;
import com.micro.platform.oauth.framework.exception.OauthException;
import com.micro.platform.oauth.framework.exception.OauthExceptionEnum;
import com.micro.platform.oauth.framework.interfaces.ITokenGranter;
import com.micro.platform.starter.utils.AssertUtil;
import com.micro.platform.starter.utils.MapUtils;
import com.micro.platform.starter.utils.NumberUtils;
import com.micro.platform.starter.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class RefreshTokenTokenGranter implements ITokenGranter {
    private String grantType = "refresh_token";
    private OauthManager oauthManager;
    public RefreshTokenTokenGranter(OauthManager oauthManager) {
        log.info("RefreshTokenTokenGranter created!");
        this.oauthManager = oauthManager;
    }

    @Override
    public OauthContext grant(OauthRequest request) {
        String refreshTokenStr = request.getRefreshToken();
        if(StringUtils.isEmpty(refreshTokenStr)){
            throw new OauthException(OauthExceptionEnum.RefreshTokenIsNotEmpty);
        }
        RefreshToken refreshToken = oauthManager.getRefreshToken(refreshTokenStr);
        if(refreshToken == null){
            throw new OauthException(OauthExceptionEnum.RefreshTokenValidateFiled);
        }
        ClientDetails clientDetails = this.oauthManager.getClientDetailsService().loadClientDetailsByClientId(refreshToken.getClientId());
        if(null == clientDetails){
            throw new OauthException(OauthExceptionEnum.ClientIdIsNotExist);
        }

        String publicKey = parsePublicKey(refreshToken);
        LocalClientDetails clientDetails1 = (LocalClientDetails) clientDetails;
        Integer secretKeyType = clientDetails1.getSecretKeyType();
        if(NumberUtils.equalsInteger(0, secretKeyType)){
            clientDetails1.setPublicKey(publicKey);
        }
        AssertUtil.notEmptyString(clientDetails1.getPublicKey(), "客户端公钥不能为空");

        UserDetails userDetails = this.oauthManager.getUserDetailsService().loadUserDetailsByAccount(refreshToken.getAccount());
        if(null == userDetails){
            throw new OauthException(OauthExceptionEnum.UserIdIsNotExist);
        }
        OauthContext oauthContext = new OauthContext(userDetails, request, clientDetails);
        return oauthContext;
    }

    private String parsePublicKey(RefreshToken refreshToken) {
        return MapUtils.getString(refreshToken.getData(), "publicKey");
    }

    @Override
    public String getGrantType() {
        return grantType;
    }
}
